<?php
/**
 * Created by PhpStorm.
 * User: Mysic
 * Date: 2020/12/23
 * Time: 16:17
 */

namespace app\common\mysic\profitShare\procedures;

use app\common\model\divide\Receive;
use app\common\model\divide\ReceivesLog;
use app\common\model\User;
use app\common\model\Order;
use app\common\model\Wxsetting;
use app\common\mysic\MysicBase;

class Receives extends MysicBase
{
    const NOT_FINISHED = 0;
    const FINISHED = 1;

    public function create(Order $userOrderEntity, Wxsetting $wxSetting, User $userEntity, $profitUpperLimit)
    {
        $model                                               = new Receive();
        $model->user_id                                      = $userOrderEntity->user_id;
        $model->account                                      = $userEntity->open_id;
        $model->order_no                                     = $userOrderEntity->order_no;
        $model->wxapp_id                                     = $userOrderEntity->wxapp_id;
        $model->payment                                      = $userOrderEntity->pay_price;
        $model->periods_num                                  = $wxSetting->periods_num;
        $model->transaction_id                               = $userOrderEntity->transaction_id;
        $model->top_limit                                    = $profitUpperLimit;
        $model->type                                         = 0;
        $model->balance                                      = $profitUpperLimit;
        $model->total_abonus                                 = 0;
        $model->times                                        = 0;
        $model->reward_money                                 = 0;
        $model->refund_money                                 = 0;
        $model->small_change                                 = 0;
        $model->is_large                                     = 1;
        $model->create_time                                  = \time();
        $model->update_time                                  = \time();
        $model->finish_time                                  = \time() + intval($wxSetting->term) * 24 * 60 * 60;
        $ret                                                 = $model->isUpdate(false)->save();
        $entity = $model->where('order_no', $userOrderEntity->order_no)->find();
        RuntimeVariables::setReceivesEntities([$userOrderEntity->order_no => $entity]);
        return $ret;
    }

    public function receivesUpdate(array $receivesEntities, array $receivesLogEntities): bool
    {
        $model = new Receive();
        $updateData = [];
        array_walk($receivesEntities, function($receivesEntity) use (&$updateData, $receivesLogEntities){
            $refundMoney = $receivesLogEntities[$receivesEntity->order_no]->refund_fee;
            $bonusType = $receivesLogEntities[$receivesEntity->order_no]->refund_type;
            $data = [
                'receives_id' => $receivesEntity->receives_id,
                'times' => $receivesEntity->times + 1,
                'balance' => $receivesEntity->balance - $refundMoney < 0 ? 0 : $receivesEntity->balance - $refundMoney,
                'total_abonus' => $receivesEntity->total_abonus += $refundMoney,
                'type' => $receivesEntity->type,
                'update_time' => \time()
            ];
            if($bonusType == ProfitShare::BONUS_REWARD) {
                $receivesEntity->reward_money =  $data['reward_money'] = $receivesEntity->reward_money += $refundMoney;
            } elseif($bonusType == ProfitShare::BONUS_REFUND) {
                $receivesEntity->refund_money = $data['refund_money'] = $receivesEntity->refund_money += $refundMoney;
            } elseif($bonusType == ProfitShare::BONUS_BALANCE) {
                $receivesEntity->small_change = $data['small_change'] = $receivesEntity->small_change += $refundMoney;
            }
            $updateData[] = $data;
            $receivesEntity->times = $data['times'];
            $receivesEntity->balance = $data['balance'];
            $receivesEntity->total_abonus = $data['total_abonus'];
            $receivesEntity->type = $data['type'];
            $receivesEntity->update_time = $data['update_time'];
        });
        try {
            $ret = $model->isUpdate()->saveAll($updateData);
            if(!$ret) {
                return false;
            }
            RuntimeVariables::setReceivesEntities($receivesEntities);
            return true;
        } catch (\Exception $e) {
            $this->log->error(exceptionLogFormat($e), '批量更新订单分红信息时异常');
            return false;
        }
    }

    public function createReceivesLog(array $receiveEntities, $paidOrderNo, $paidPayPrice, $receiveEntitiesProfitMap, $apiType): bool
    {
        $model = new ReceivesLog();
        $insertData = [];
        foreach($receiveEntities as $receiveEntity) {
            $data = [
                'wxapp_id' => $receiveEntity->wxapp_id,
                'receives_id' => $receiveEntity->receives_id,
                'order_no' => $paidOrderNo,
                'receives_order_no' => $receiveEntity->order_no,
                'profit_sharing_sn' => '',
                'refund_type' => 0,
                'api_type' => $apiType,
                'refund_id' => '',
                'refund_fee' => $receiveEntitiesProfitMap[$receiveEntity->order_no],
                'money' => $paidPayPrice,
                'status' => 0,
                'times' => 0,
                'create_time' => time(),
                'update_time' => time()
            ];
            $insertData[] = $data;
        }
        $this->log->info($insertData, '创建receivesLog数据');
        $ret = $model->insertAll($insertData);
        $receivesLogEntities = $model->where('order_no', $paidOrderNo)->select();
        $receivesLogEntities = $receivesLogEntities->all();
        RuntimeVariables::setReceivesLogEntities($receivesLogEntities);
        return $ret;
    }

    public function updateReceivesLog(array $receivesEntities, array $receivesLogEntities, $paidOrderNo, $bonusType, $refundId = '', $status = 1): bool
    {
        $model = new ReceivesLog();
        $updateData = [];
        foreach($receivesEntities as $receivesEntity) {
            $data = [
                'id' => $receivesLogEntities[$receivesEntity->order_no]->id,
                'order_no' => $paidOrderNo,
                'receives_order_no' => $receivesEntity->order_no,
                'profit_sharing_sn' => $receivesLogEntities[$receivesEntity->order_no]->profit_sharing_sn ?? '',
                'refund_type' => $bonusType,
                'times' => $receivesEntity->times,
                'refund_id' => $refundId,
                'status' => $status
            ];
            $updateData[] = $data;
        }
        try {
            $model->isUpdate()->saveAll($updateData);
        } catch (\Exception $e) {
            $this->log->error(exceptionLogFormat($e), '更新分红流水时异常');
            return false;
        }
        return true;
    }

    public function isFinished($profitUpperLimit, $profit, $balance, $finishTime): bool
    {
        if($profitUpperLimit <= $profit) {
            return true;
        }
        if($balance <= 0) {
            return true;
        }
        if(bccomp(strval($profit), strval($balance), 2) >= 0) {
            return true;
        }
        if($finishTime <= time()) {
            return true;
        }
        return false;
    }
}